package edu.usx.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import edu.usx.server.mapper.UserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import edu.usx.server.config.security.JwtTokenUtil;
import edu.usx.server.pojo.Admin;
import edu.usx.server.mapper.AdminMapper;
import edu.usx.server.pojo.RespBean;
import edu.usx.server.pojo.User;
import edu.usx.server.pojo.RespBean;
import edu.usx.server.service.IAdminService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.usx.server.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Priority;
import javax.annotation.Resource;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Usx
 * @since 2024-07-18
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements IAdminService {
    @Resource
    private IUserService userService;
    @Resource
    private UserMapper userMapper;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RespBean editRole(Integer id,Integer role_id) {
        if (id == null || role_id == null ) {
            return RespBean.error("无效的参数");
        }
        User user = userService.getById(id);
        if (user==null) {
            return RespBean.error("用户不存在");
        }

        user.setRole_id(role_id);

        userMapper.update(user);

        return RespBean.success("修改用户权限成功");
    }

    /**
     * 管理员登录
     * @param username
     * @param password
     * @param request
     * @return
     */
    @Override
    public RespBean login(String username, String password, String code, HttpServletRequest request) {
        String captcha=(String) request.getSession().getAttribute("captcha");
        if(StringUtils.isEmpty(code)||!captcha.equalsIgnoreCase(code)){
            return RespBean.error("验证码错误，请重新输入！");
        }
        UserDetails userDetails=userDetailsService.loadUserByUsername(username);
        //账号判断
        if(userDetails==null||!passwordEncoder.matches(password,userDetails.getPassword())){
            return RespBean.error("用户名或密码不正确");
        }
        if(!userDetails.isEnabled()){
            return RespBean.error("账号被禁用！");
        }
        //更新security登录用户对象
        UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(userDetails,
                null,userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //生成token
        String token=jwtTokenUtil.generateToken(userDetails);
        Map<String,String> tokenMap=new HashMap<>();
        tokenMap.put("token",token);
        tokenMap.put("tokenHead",tokenHead);
        return RespBean.success("登录成功！",tokenMap);
    }

    /**
     * 获取管理员登录信息
     * @param username
     * @return
     */
    @Override
    public Admin getUserByUserName(String username) {
        Admin admin = new Admin();
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<Admin>();
        wrapper = wrapper.select().eq(Admin::getUsername, username);
        admin = baseMapper.selectOne(wrapper);
        return admin;
    }
}
